package com.example.sihookuiklydemo.base

import com.tencent.kuikly.core.base.Color
import com.tencent.kuikly.core.base.ComposeView
import com.tencent.kuikly.core.base.ComposeAttr
import com.tencent.kuikly.core.base.ComposeEvent
import com.tencent.kuikly.core.base.ViewBuilder
import com.tencent.kuikly.core.base.ViewContainer
import com.tencent.kuikly.core.base.event.didAppear
import com.tencent.kuikly.core.log.KLog
import com.tencent.kuikly.core.reactive.handler.observable
import com.tencent.kuikly.core.timer.setTimeout
import com.tencent.kuikly.core.views.ScrollParams
import com.tencent.kuikly.core.views.Scroller
import com.tencent.kuikly.core.views.SpringAnimation
import com.tencent.kuikly.core.views.Text
import com.tencent.kuikly.core.views.View
import kotlin.math.max
import kotlin.math.min

internal typealias ScrollPickerDragEndEvent = (centerValue: String, centerItemIndex: Int) -> Unit

internal class MyScrollPickerView(
    private val itemList: List<String>,
    private val defaultIndex: Int? = null
) : ComposeView<MyScrollPickerViewAttr, MyScrollPickerViewEvent>() {
    var centerItemIndex by observable(0)
    override fun createEvent(): MyScrollPickerViewEvent {
        return MyScrollPickerViewEvent()
    }

    override fun createAttr(): MyScrollPickerViewAttr {
        return MyScrollPickerViewAttr()
    }

    private fun scrollOffset(params: ScrollParams, dataListSize: Int): Float {
        val ctx = this@MyScrollPickerView
        var temp = params.offsetY
        if (temp.toInt() % ctx.attr.itemHeight > ctx.attr.itemHeight / 2) {
            temp += ctx.attr.itemHeight
        }
        val offsetValue =
            temp - params.offsetY.toInt() % ctx.attr.itemHeight
        val finOffSet = min(
            max(0f, offsetValue),
            (dataListSize) * ctx.attr.itemHeight - ctx.attr.countPerScreen * ctx.attr.itemHeight
        )
        return finOffSet
    }

    override fun created() {
        super.created()

    }
    override fun body(): ViewBuilder {
        val ctx = this@MyScrollPickerView
        val itemHeight = ctx.attr.itemHeight
        val itemWidth = ctx.attr.itemWidth
        val offset = ctx.attr.countPerScreen / 2
        ctx.centerItemIndex = ctx.defaultIndex ?: 0
        return {
            Scroller {
                val dataList = arrayListOf<String>()
                val placeHolderArray = Array<String>(offset) { "" }
                dataList.addAll(placeHolderArray)
                dataList.addAll(ctx.itemList)
                dataList.addAll(placeHolderArray)
                val scroller = this@Scroller
                var targetIndex = 0
                attr {
                    showScrollerIndicator(false)
                    width(itemWidth)
                    height(ctx.attr.countPerScreen * itemHeight)
                    flexDirectionColumn()
                    allCenter()
                    bouncesEnable(true)
                }
                event {
                    didAppear {
                        ctx.event.dragEndEvent(dataList[offset], 0)
                        if (ctx.defaultIndex != null && ctx.defaultIndex > 0 && ctx.defaultIndex < ctx.itemList.size) {

                            setTimeout(10) {
                                if(ctx.attr.animatedToSelected){
                                    scroller.setContentOffset(
                                        0f,
                                        ctx.attr.itemHeight * ctx.defaultIndex,
                                        true, SpringAnimation(200,1.0f, 1f)

                                    )
                                }else{
                                    scroller.setContentOffset(
                                        0f,
                                        ctx.attr.itemHeight * ctx.defaultIndex,
                                        false
                                    )
                                }

                                ctx.event.dragEndEvent(
                                    dataList[ctx.defaultIndex + offset],
                                    ctx.defaultIndex
                                )
                            }
                        }
                    }
                    click { params ->
                        val temp = params.y - 2 * itemHeight
                        val offsetValue =
                            temp - params.y.toInt() % itemHeight
                        val finOffSet = min(
                            max(0f, offsetValue),
                            (dataList.size) * itemHeight - ctx.attr.countPerScreen * itemHeight
                        )
                        scroller.setContentOffset(0f, finOffSet, true)
                        val centerIndex = (finOffSet / itemHeight).toInt()
                        ctx.event.dragEndEvent(dataList[centerIndex + offset], centerIndex)
                    }

                    willDragEndBySync {
                        val params = ScrollParams(
                            offsetX = it.offsetX,
                            offsetY = it.offsetY,
                            contentHeight = it.contentHeight,
                            contentWidth = it.contentWidth,
                            viewHeight = it.viewHeight,
                            viewWidth = it.viewWidth,
                            isDragging = it.isDragging
                        )
                        val finOffSet = ctx.scrollOffset(params, dataList.size)
                        scroller.setContentOffset(
                            0f,
                            finOffSet,
                            true,
                            SpringAnimation(200, 1.0f, it.velocityY)
                        )
                        targetIndex =
                            (finOffSet / ctx.attr.itemHeight).toInt()
                        KLog.i("willDragEndBySync", "targetIndex ${targetIndex}")
                    }
                    dragEnd {
                        val finOffSet = ctx.scrollOffset(it, dataList.size)
                        scroller.setContentOffset(
                            0f,
                            finOffSet,
                            true,
                            SpringAnimation(200, 1.0f, 1f)
                        )
                        targetIndex =
                            (finOffSet / ctx.attr.itemHeight).toInt()
                        ctx.event.dragEndEvent(dataList[targetIndex + offset], targetIndex)
                        ctx.centerItemIndex = targetIndex
                        KLog.i("dragEnd", "targetIndex ${targetIndex}")
                    }
                }
                dataList.forEachIndexed { index, s ->
                    View {
                        attr {
                            size(ctx.attr.itemWidth, ctx.attr.itemHeight)
                            allCenter()
                            backgroundColor(ctx.attr.itemBackGroundColor)
                        }
                        Text {
                            attr {
                                var isSelected = index == ctx.centerItemIndex + offset
                                text(s)
                                useDpFontSizeDim(true)
                                minWidth(ctx.attr.itemWidth)
                                textAlignCenter()
                                fontSize( ctx.attr.itemFontSize)
                                KLog.i("text", "body:targetIndex $index $s ${ctx.centerItemIndex}")
                                color(if (isSelected) ctx.attr.itemTextColorCenter else ctx.attr.itemTextColor)
                            }
                        }
                    }
                }
            }
        }
    }
}


internal class MyScrollPickerViewAttr : ComposeAttr() {
    // 单个item选项的高度
    var itemWidth: Float = 0f

    // 单个item选项的高度
    var itemHeight: Float = 0f

    // 每屏item的个数
    var countPerScreen: Int = 0

    //每个item的背景色
    var itemBackGroundColor: Color = Color.TRANSPARENT

    //每个item的文字色
    var itemTextColor: Color = Color.GRAY
    var itemTextColorCenter = Color.BLACK
    var itemFontSize = 17f
    var itemFontSizeCenter = 19f
    var animatedToSelected=true
}

internal class MyScrollPickerViewEvent : ComposeEvent() {
    lateinit var dragEndEvent: ScrollPickerDragEndEvent

    // 停止滚动后选中item，回调中间的value和index
    fun dragEndEvent(event: ScrollPickerDragEndEvent) {
        dragEndEvent = event
    }
}

internal fun ViewContainer<*, *>.MyScrollPicker(
    itemList: List<String>,
    defaultIndex: Int? = null,
    init: MyScrollPickerView.() -> Unit
) {
    addChild(MyScrollPickerView(itemList, defaultIndex), init)
}